"""
过滤器组件
提供各种数据过滤和筛选组件
"""

import streamlit as st
import pandas as pd
from typing import Dict, List, Any, Optional, Union, Tuple
from datetime import datetime, date, timedelta
import numpy as np


def create_date_filter(
    label: str = "日期范围",
    default_start: Optional[date] = None,
    default_end: Optional[date] = None,
    key: Optional[str] = None
) -> Tuple[date, date]:
    """
    创建日期范围过滤器
    
    Args:
        label: 标签
        default_start: 默认开始日期
        default_end: 默认结束日期
        key: 组件键
    
    Returns:
        (开始日期, 结束日期)
    """
    if default_start is None:
        default_start = date.today() - timedelta(days=30)
    if default_end is None:
        default_end = date.today()
    
    col1, col2 = st.columns(2)
    
    with col1:
        start_date = st.date_input(
            "开始日期",
            value=default_start,
            key=f"{key}_start" if key else None
        )
    
    with col2:
        end_date = st.date_input(
            "结束日期",
            value=default_end,
            key=f"{key}_end" if key else None
        )
    
    return start_date, end_date


def create_multiselect_filter(
    data: pd.DataFrame,
    column: str,
    label: Optional[str] = None,
    default: Optional[List[Any]] = None,
    key: Optional[str] = None
) -> List[Any]:
    """
    创建多选过滤器
    
    Args:
        data: 数据框
        column: 列名
        label: 标签
        default: 默认选择
        key: 组件键
    
    Returns:
        选择的值列表
    """
    if column not in data.columns:
        st.error(f"列 '{column}' 不存在")
        return []
    
    if label is None:
        label = column
    
    # 获取唯一值
    unique_values = sorted(data[column].dropna().unique().tolist())
    
    if default is None:
        default = unique_values
    
    selected = st.multiselect(
        label,
        options=unique_values,
        default=default,
        key=key
    )
    
    return selected


def create_range_filter(
    data: pd.DataFrame,
    column: str,
    label: Optional[str] = None,
    key: Optional[str] = None
) -> Tuple[float, float]:
    """
    创建数值范围过滤器
    
    Args:
        data: 数据框
        column: 列名
        label: 标签
        key: 组件键
    
    Returns:
        (最小值, 最大值)
    """
    if column not in data.columns:
        st.error(f"列 '{column}' 不存在")
        return 0.0, 0.0
    
    if label is None:
        label = column
    
    # 获取数值范围
    numeric_data = pd.to_numeric(data[column], errors='coerce').dropna()
    
    if numeric_data.empty:
        st.warning(f"列 '{column}' 没有有效的数值数据")
        return 0.0, 0.0
    
    min_val = float(numeric_data.min())
    max_val = float(numeric_data.max())
    
    # 创建滑块
    selected_range = st.slider(
        label,
        min_value=min_val,
        max_value=max_val,
        value=(min_val, max_val),
        key=key
    )
    
    return selected_range


def create_text_filter(
    label: str = "文本搜索",
    placeholder: str = "输入搜索关键词...",
    key: Optional[str] = None
) -> str:
    """
    创建文本搜索过滤器
    
    Args:
        label: 标签
        placeholder: 占位符
        key: 组件键
    
    Returns:
        搜索文本
    """
    search_text = st.text_input(
        label,
        placeholder=placeholder,
        key=key
    )
    
    return search_text.strip()


def create_category_filter(
    categories: List[str],
    label: str = "选择类别",
    default: Optional[str] = None,
    key: Optional[str] = None
) -> str:
    """
    创建类别选择过滤器
    
    Args:
        categories: 类别列表
        label: 标签
        default: 默认选择
        key: 组件键
    
    Returns:
        选择的类别
    """
    if default is None and categories:
        default = categories[0]
    
    selected = st.selectbox(
        label,
        options=categories,
        index=categories.index(default) if default in categories else 0,
        key=key
    )
    
    return selected


def create_boolean_filter(
    label: str,
    default: bool = True,
    key: Optional[str] = None
) -> bool:
    """
    创建布尔过滤器
    
    Args:
        label: 标签
        default: 默认值
        key: 组件键
    
    Returns:
        布尔值
    """
    return st.checkbox(label, value=default, key=key)


def create_advanced_filter_panel(
    data: pd.DataFrame,
    title: str = "高级过滤器"
) -> Dict[str, Any]:
    """
    创建高级过滤器面板
    
    Args:
        data: 数据框
        title: 面板标题
    
    Returns:
        过滤器配置字典
    """
    with st.expander(title):
        filters = {}
        
        # 列选择
        st.subheader("列过滤")
        all_columns = data.columns.tolist()
        selected_columns = st.multiselect(
            "选择要显示的列",
            options=all_columns,
            default=all_columns,
            key="column_filter"
        )
        filters['columns'] = selected_columns
        
        # 行过滤
        st.subheader("行过滤")
        
        # 文本列过滤
        text_columns = data.select_dtypes(include=['object', 'string']).columns.tolist()
        if text_columns:
            st.write("**文本列过滤**")
            for col in text_columns[:3]:  # 限制显示前3个文本列
                search_term = st.text_input(
                    f"搜索 {col}",
                    key=f"text_filter_{col}"
                )
                if search_term:
                    filters[f'text_{col}'] = search_term
        
        # 数值列过滤
        numeric_columns = data.select_dtypes(include=[np.number]).columns.tolist()
        if numeric_columns:
            st.write("**数值列过滤**")
            for col in numeric_columns[:3]:  # 限制显示前3个数值列
                if not data[col].isna().all():
                    min_val = float(data[col].min())
                    max_val = float(data[col].max())
                    
                    if min_val != max_val:
                        range_val = st.slider(
                            f"{col} 范围",
                            min_value=min_val,
                            max_value=max_val,
                            value=(min_val, max_val),
                            key=f"range_filter_{col}"
                        )
                        filters[f'range_{col}'] = range_val
        
        # 排序选项
        st.subheader("排序")
        sort_column = st.selectbox(
            "排序列",
            options=['无'] + all_columns,
            key="sort_column"
        )
        
        if sort_column != '无':
            sort_ascending = st.radio(
                "排序方向",
                options=['升序', '降序'],
                key="sort_direction"
            ) == '升序'
            
            filters['sort'] = {
                'column': sort_column,
                'ascending': sort_ascending
            }
        
        return filters


def apply_filters(data: pd.DataFrame, filters: Dict[str, Any]) -> pd.DataFrame:
    """
    应用过滤器到数据框
    
    Args:
        data: 原始数据框
        filters: 过滤器配置
    
    Returns:
        过滤后的数据框
    """
    filtered_data = data.copy()
    
    # 应用文本过滤器
    for key, value in filters.items():
        if key.startswith('text_') and value:
            column = key.replace('text_', '')
            if column in filtered_data.columns:
                mask = filtered_data[column].astype(str).str.contains(
                    value, case=False, na=False
                )
                filtered_data = filtered_data[mask]
    
    # 应用范围过滤器
    for key, value in filters.items():
        if key.startswith('range_') and value:
            column = key.replace('range_', '')
            if column in filtered_data.columns:
                min_val, max_val = value
                mask = (filtered_data[column] >= min_val) & (filtered_data[column] <= max_val)
                filtered_data = filtered_data[mask]
    
    # 应用列过滤器
    if 'columns' in filters and filters['columns']:
        available_columns = [col for col in filters['columns'] if col in filtered_data.columns]
        if available_columns:
            filtered_data = filtered_data[available_columns]
    
    # 应用排序
    if 'sort' in filters:
        sort_config = filters['sort']
        if sort_config['column'] in filtered_data.columns:
            filtered_data = filtered_data.sort_values(
                sort_config['column'],
                ascending=sort_config['ascending']
            )
    
    return filtered_data


def create_quick_filters(
    data: pd.DataFrame,
    quick_filter_configs: List[Dict[str, Any]]
) -> Dict[str, Any]:
    """
    创建快速过滤器
    
    Args:
        data: 数据框
        quick_filter_configs: 快速过滤器配置列表
            每个配置包含: {
                'type': 'multiselect'|'range'|'text'|'date'|'boolean',
                'column': '列名',
                'label': '显示标签',
                'key': '组件键'
            }
    
    Returns:
        过滤器值字典
    """
    st.subheader("快速过滤")
    
    filters = {}
    cols = st.columns(min(len(quick_filter_configs), 4))
    
    for i, config in enumerate(quick_filter_configs):
        col_idx = i % len(cols)
        
        with cols[col_idx]:
            filter_type = config.get('type', 'text')
            column = config.get('column')
            label = config.get('label', column)
            key = config.get('key', f"quick_filter_{i}")
            
            if filter_type == 'multiselect' and column in data.columns:
                filters[key] = create_multiselect_filter(
                    data, column, label, key=key
                )
            
            elif filter_type == 'range' and column in data.columns:
                filters[key] = create_range_filter(
                    data, column, label, key=key
                )
            
            elif filter_type == 'text':
                filters[key] = create_text_filter(
                    label, key=key
                )
            
            elif filter_type == 'date':
                filters[key] = create_date_filter(
                    label, key=key
                )
            
            elif filter_type == 'boolean':
                filters[key] = create_boolean_filter(
                    label, key=key
                )
    
    return filters


def create_filter_summary(filters: Dict[str, Any]) -> None:
    """
    创建过滤器摘要显示
    
    Args:
        filters: 过滤器字典
    """
    active_filters = {k: v for k, v in filters.items() if v}
    
    if active_filters:
        st.info(f"当前激活 {len(active_filters)} 个过滤器")
        
        with st.expander("查看过滤器详情"):
            for key, value in active_filters.items():
                if isinstance(value, (list, tuple)):
                    if len(value) > 0:
                        st.write(f"**{key}**: {', '.join(map(str, value))}")
                else:
                    st.write(f"**{key}**: {value}")
    else:
        st.info("未应用任何过滤器")


def create_saved_filters_manager(
    current_filters: Dict[str, Any],
    key: str = "saved_filters"
) -> Dict[str, Any]:
    """
    创建保存的过滤器管理器
    
    Args:
        current_filters: 当前过滤器配置
        key: 存储键
    
    Returns:
        选择的过滤器配置
    """
    st.subheader("过滤器管理")
    
    # 初始化session state
    if f"{key}_saved" not in st.session_state:
        st.session_state[f"{key}_saved"] = {}
    
    col1, col2, col3 = st.columns(3)
    
    with col1:
        # 保存当前过滤器
        save_name = st.text_input("过滤器名称", key=f"{key}_save_name")
        if st.button("保存过滤器", key=f"{key}_save_btn"):
            if save_name and current_filters:
                st.session_state[f"{key}_saved"][save_name] = current_filters.copy()
                st.success(f"过滤器 '{save_name}' 已保存")
    
    with col2:
        # 加载保存的过滤器
        saved_names = list(st.session_state[f"{key}_saved"].keys())
        if saved_names:
            selected_filter = st.selectbox(
                "选择保存的过滤器",
                options=[''] + saved_names,
                key=f"{key}_load_select"
            )
            
            if st.button("加载过滤器", key=f"{key}_load_btn") and selected_filter:
                return st.session_state[f"{key}_saved"][selected_filter]
    
    with col3:
        # 删除保存的过滤器
        if saved_names:
            delete_filter = st.selectbox(
                "删除过滤器",
                options=[''] + saved_names,
                key=f"{key}_delete_select"
            )
            
            if st.button("删除过滤器", key=f"{key}_delete_btn") and delete_filter:
                del st.session_state[f"{key}_saved"][delete_filter]
                st.success(f"过滤器 '{delete_filter}' 已删除")
                st.rerun()
    
    # 显示保存的过滤器列表
    if saved_names:
        st.write("**已保存的过滤器:**")
        for name in saved_names:
            st.write(f"- {name}")
    
    return current_filters


def create_dynamic_filter_builder(data: pd.DataFrame) -> Dict[str, Any]:
    """
    创建动态过滤器构建器
    
    Args:
        data: 数据框
    
    Returns:
        构建的过滤器配置
    """
    st.subheader("动态过滤器构建器")
    
    filters = {}
    
    # 初始化过滤器数量
    if 'filter_count' not in st.session_state:
        st.session_state.filter_count = 1
    
    # 添加/删除过滤器按钮
    col1, col2 = st.columns(2)
    with col1:
        if st.button("➕ 添加过滤器"):
            st.session_state.filter_count += 1
    
    with col2:
        if st.button("➖ 删除过滤器") and st.session_state.filter_count > 1:
            st.session_state.filter_count -= 1
    
    # 创建动态过滤器
    for i in range(st.session_state.filter_count):
        st.write(f"**过滤器 {i+1}**")
        
        col1, col2, col3 = st.columns(3)
        
        with col1:
            # 选择列
            column = st.selectbox(
                "选择列",
                options=data.columns.tolist(),
                key=f"dynamic_column_{i}"
            )
        
        with col2:
            # 选择操作类型
            if data[column].dtype in ['object', 'string']:
                operations = ['包含', '等于', '不等于']
            else:
                operations = ['等于', '大于', '小于', '大于等于', '小于等于', '范围']
            
            operation = st.selectbox(
                "操作",
                options=operations,
                key=f"dynamic_operation_{i}"
            )
        
        with col3:
            # 输入值
            if operation == '范围':
                min_val = float(data[column].min())
                max_val = float(data[column].max())
                value = st.slider(
                    "值范围",
                    min_value=min_val,
                    max_value=max_val,
                    value=(min_val, max_val),
                    key=f"dynamic_value_{i}"
                )
            elif data[column].dtype in ['object', 'string']:
                if operation in ['包含', '等于', '不等于']:
                    value = st.text_input(
                        "值",
                        key=f"dynamic_value_{i}"
                    )
            else:
                value = st.number_input(
                    "值",
                    value=float(data[column].mean()),
                    key=f"dynamic_value_{i}"
                )
        
        # 保存过滤器配置
        filters[f"filter_{i}"] = {
            'column': column,
            'operation': operation,
            'value': value
        }
        
        st.divider()
    
    return filters


def apply_dynamic_filters(data: pd.DataFrame, filters: Dict[str, Any]) -> pd.DataFrame:
    """
    应用动态过滤器
    
    Args:
        data: 原始数据框
        filters: 动态过滤器配置
    
    Returns:
        过滤后的数据框
    """
    filtered_data = data.copy()
    
    for filter_config in filters.values():
        if not isinstance(filter_config, dict):
            continue
            
        column = filter_config.get('column')
        operation = filter_config.get('operation')
        value = filter_config.get('value')
        
        if not all([column, operation, value is not None]):
            continue
        
        if column not in filtered_data.columns:
            continue
        
        # 应用过滤条件
        if operation == '等于':
            mask = filtered_data[column] == value
        elif operation == '不等于':
            mask = filtered_data[column] != value
        elif operation == '大于':
            mask = filtered_data[column] > value
        elif operation == '小于':
            mask = filtered_data[column] < value
        elif operation == '大于等于':
            mask = filtered_data[column] >= value
        elif operation == '小于等于':
            mask = filtered_data[column] <= value
        elif operation == '包含':
            mask = filtered_data[column].astype(str).str.contains(str(value), case=False, na=False)
        elif operation == '范围':
            min_val, max_val = value
            mask = (filtered_data[column] >= min_val) & (filtered_data[column] <= max_val)
        else:
            continue
        
        filtered_data = filtered_data[mask]
    
    return filtered_data